<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import signInPopup from "@/components/signInPopup.vue";
import task from "@/components/task.vue";
import genderPopup from "@/components/genderPopup.vue";
import coBreeding from "@/components/coBreeding.vue";
import congratulationOne from "@/components/congratulationOne.vue";
import congratulationTwo from "@/components/congratulationTwo.vue";
import diaryPopup from "@/components/diaryPopup.vue";
import trackPopup from "@/components/trackPopup.vue";
import myDetails from "@/components/myDetails.vue";
import setting from "@/components/setting.vue";
import friendPopup from "@/components/friendPopup.vue";
import walk from "./walk.vue";
import rightPersonage from "@/assets/image/right-personage.png";
import rightMap from "@/assets/image/right-map.png";
import rightTask from "@/assets/image/right-task.png";
import rightTrack from "@/assets/image/right-track.png";
import rightMore from "@/assets/image/right-more.png";
import rightDiary from "@/assets/image/right-diary.png";
import rightMoreFirend from "@/assets/image/right-more-firend.png";
import rightMoreSetting from "@/assets/image/right-more-setting.png";
import { getQueryPage, getTaskList } from "@/api/common";
import { skipToApp } from "@/utils/common";
import AddFriendPopup from "@/components/addFriendPopup.vue";
import { useAnimationStore, useMainStore } from "@/store";
import { useRouter } from "vue-router";
const bottom = [
  {
    src: new URL("@/assets/image/bottom/school.png", import.meta.url).href,
    name: "school",
    url: "/campus",
  },
  {
    src: new URL("@/assets/image/bottom/lezhi.png", import.meta.url).href,
    name: "lezhi",
    url: "",
  },
  {
    src: new URL("@/assets/image/bottom/my.png", import.meta.url).href,
    name: "my",
    url: "/my",
  },
];
const isOpen = ref(false);
const signInPopupShow = ref(false);
const genderPopupShow = ref(false);
const coBreedingpShow = ref(false);
const congratulationTwoShow = ref(false);
const congratulationOneShow = ref(false);
const diaryShow = ref(false);
const trackPopupShow = ref(false);
const myDetailsShow = ref(false);
const friendPopupShow = ref(false);
const taskShow = ref(false);
const settingShow = ref(false);
const addFriendPopupShow = ref(false);
const rightBoxShow = ref(true);
const bottomBoxShow = ref(true);
const positioningRef = ref<HTMLElement>();
const animationStore = useAnimationStore();
const animationList = computed(() => animationStore.list);
const rightBox = [
  {
    src: rightPersonage,
    name: "personage",
    click: () => {
      myDetailsShow.value = true;
    },
  },
  {
    src: rightMap,
    name: "map",
    click: () => {},
  },
  {
    src: rightDiary,
    name: "diary",
    click: () => {
      diaryShow.value = true;
    },
  },
  {
    src: rightTask,
    name: "task",
    click: () => {
      taskShow.value = true;
    },
  },
  {
    src: rightTrack,
    name: "track",
    click: () => {
      trackPopupShow.value = true;
    },
  },
  {
    src: rightMore,
    name: "more",
    click: () => {
      arrowsClick();
    },
  },
];
const pagination = ref({
  pageNum: 1,
  pageSize: 10,
  searchCount: true,
  sortItemList: [
    {
      isAsc: false,
      column: "sort",
    },
  ],
});
const moreItemBox = [
  {
    src: rightMoreFirend,
    name: "friend",
    text: "好友",
    click: () => {
      friendPopupShow.value = true;
    },
  },
  {
    src: rightMoreSetting,
    name: "setting",
    text: "设置",
    click: () => {
      settingShow.value = true;
    },
  },
];
const positioning: any = {
  HOME: {
    bottom: "88px",
    left: "240px",
  },
  CLASSROOM: {
    bottom: "312px",
    left: "232px",
  },
  LIBRARY: {
    bottom: "438px",
    left: "140px",
  },
  GYM: {
    bottom: "550px",
    left: "55px",
  },
  PLAYGROUND: {
    bottom: "550px",
    left: "55px",
  },
  CANTEEN: {
    bottom: "500px",
    left: "270px",
  },
  DORMITORY: {
    bottom: "695px",
    left: "165px",
  },
};
const rightArrows = ref<HTMLElement>();
const signInTask = ref();
const bottomBtnList = ref();
const childTaskSelect = computed(() => {
  return mainStore.cobreedingTaskId;
});
const presentKey = ref("0");
watch(
  () => animationList.value,
  (newValue) => {
    if (newValue.length) {
      animationFunction(newValue);
    }
  }
);
function setPosition(key: string): Promise<void> {
  return new Promise((resolve) => {
    const currentBottom =
      positioningRef.value?.style.bottom || positioning["HOME"].bottom;
    const currentLeft =
      positioningRef.value?.style.left || positioning["HOME"].left;
    // 创建关键帧动画
    presentKey.value = key;
    const animationName = `moveTo_${key}`;
    const animationRule = `
      @keyframes ${animationName} {
        from {
          bottom: ${currentBottom};
          left: ${currentLeft};
        }
        to {
          bottom: ${positioning[key].bottom};
          left: ${positioning[key].left};
        }
      }
    `;
    // 动态添加动画
    const styleEl = document.createElement("style");
    styleEl.innerHTML = animationRule;
    document.head.appendChild(styleEl);
    // 应用动画
    positioningRef.value!.style.animation = `${animationName} 3s ease-out forwards`;
    // 监听动画结束
    positioningRef.value!.addEventListener(
      "animationend",
      () => {
        positioningRef.value!.style.bottom = positioning[key].bottom;
        positioningRef.value!.style.left = positioning[key].left;
        // 移除动画
        positioningRef.value!.style.animation = "";
        setTimeout(() => {
          resolve(); // 动画结束后解决 Promise
        }, 2000);
      },
      { once: true }
    );
  });
}

function arrowsClick() {
  if (!rightArrows.value) return;
  const computedStyle = getRotationAngle(rightArrows.value);
  if (computedStyle === -90) {
    isOpen.value = true;
    rightArrows.value.style.transform = "rotate(0deg)";
  } else {
    isOpen.value = false;
    rightArrows.value.style.transform = "rotate(-90deg)";
  }
}

function getRotationAngle(element: HTMLElement) {
  const style = window.getComputedStyle(element);
  const matrix = new DOMMatrix(style.transform);
  return Math.round((Math.atan2(matrix.b, matrix.a) * 180) / Math.PI);
}

function taskSkip(taskType: number, taskId: number) {
  if (taskType == 2) {
    signInTask.value = taskId;
    signInPopupShow.value = true;
  } else if (taskType == 3) {
    if (childTaskSelect.value) {
      congratulationTwoShow.value = true;
    } else {
      coBreedingpShow.value = true;
    }
  }
}

function skipClick(url: string) {
  // const match = url.match(/^(.*?)(\?|\#|$)/);
  // const routeUrl = match ? match[1] : "";
  // const params = getQueryParams(url);
  // if (params) {
  //   if (!params.studentId) {
  //     params.studentId = sessionStorage.getItem("studentInfo") || "";
  //   }
  //   skipToApp(routeUrl, params);
  // } else {
  //   skipToApp(routeUrl);
  // }
  skipToApp(url, { studentId: mainStore.studentInfo?.studentId });
}

function goFriendEvent() {
  friendPopupShow.value = true;
}

function skipAddFriend() {
  addFriendPopupShow.value = true;
}

const mainStore = useMainStore();
const studentInfo = computed(() => mainStore.studentInfo);
function wsInit() {
  const url = `${import.meta.env.VITE_APP_BASE_API.replace("https://", "")}${
    import.meta.env.VITE_APP_PUBLIC_PATH
  }`;
  const studentId = studentInfo.value?.studentId;
  if (!studentId) return;

  const wsUrl = `wss://${url}websocket?uniqueId=${studentId}`;
  let reconnectAttempts = 0;
  let ws: WebSocket;
  const connect = () => {
    ws = new WebSocket(wsUrl);
    ws.onopen = () => {
      console.log("WebSocket连接已打开");
      reconnectAttempts = 0; // 重置重连计数器
    };
    ws.onclose = (e) => {
      // 非正常关闭时重连
      const delay = Math.min(3000 * 2 ** reconnectAttempts, 30000); // 指数退避
    };

    ws.onerror = (error) => {
      console.error("连接错误:", error);
      ws.close(); // 触发onclose进行重连
    };

    ws.onmessage = (event) => {
      const reader = new FileReader();
      reader.onload = () => {
        const arrayBuffer = reader.result;
        const uintArray = new Uint8Array(arrayBuffer as ArrayBuffer);
        const location = uintArray.slice(41, 42);
        window.setAnimationFunction([...location]);
      };
      reader.readAsArrayBuffer(event.data);
    };
  };
  // 初始化连接
  connect();
}
function init() {
  wsInit();
  getQueryPage(pagination.value).then((res) => {
    bottomBtnList.value = res.data.list;
  });
}
onMounted(() => {
  init();
});
async function animationFunction(data: any[]) {
  trackPopupShow.value = false;
  rightBoxShow.value = false;
  bottomBoxShow.value = false;
  for (let i = 0; i < data.length; i++) {
    await setPosition(data[i]);
    if (i == data.length - 1) {
      rightBoxShow.value = true;
      bottomBoxShow.value = true;
    }
  }
}
const router = useRouter();
function playAnimation() {
  if (presentKey.value == "CANTEEN") {
    router.push("canteen");
  } else if (presentKey.value == "DORMITORY") {
    router.push("dormitory");
  } else if (presentKey.value == "LIBRARY") {
    router.push("library");
  } else if (presentKey.value == "PLAYGROUND") {
    router.push("playground");
  } else if (presentKey.value == "GYM") {
    router.push("playground");
  } else if (presentKey.value == "CLASSROOM") {
    router.push("classroom");
  }
}

function congratulationSkip() {
  coBreedingpShow.value = false;
  congratulationOneShow.value = true;
}
</script>
<template>
  <div class="vessel">
    <img
      ref="positioningRef"
      src="@/assets/image/positioning.png"
      alt="positioning"
      class="positioning-class"
      @click="playAnimation"
    />
    <div v-show="rightBoxShow" class="right-box">
      <img
        v-for="item in rightBox"
        :key="item.name"
        :src="item.src"
        :alt="item.name"
        class="right-box-item"
        @click="item.click"
      />
      <img
        src="@/assets/image/right-arrows.png"
        alt="arrows"
        ref="rightArrows"
        class="right-box-item-arrows-pack-up"
        @click="arrowsClick"
      />
      <div v-show="isOpen" class="right-more-flex-box">
        <div
          v-for="moreItem in moreItemBox"
          :key="moreItem.name"
          @click="moreItem.click"
        >
          <img :src="moreItem.src" :alt="moreItem.name" class="more-item" />
          <div>{{ moreItem.text }}</div>
        </div>
      </div>
    </div>
    <div v-show="bottomBoxShow" class="bottom-box">
      <div class="bottom-school" v-for="item in bottom" :key="item.src">
        <img
          :src="item.src"
          class="bottom-school"
          @click="skipClick(item.url)"
        />
      </div>
    </div>
  </div>
  <AddFriendPopup v-model:show-popup="addFriendPopupShow" />
  <friendPopup
    v-model:show-popup="friendPopupShow"
    @child-event="skipAddFriend"
  />
  <setting v-model:show-popup="settingShow" />
  <myDetails v-model:show-popup="myDetailsShow" @child-event="goFriendEvent" />
  <trackPopup
    v-model:show-popup="trackPopupShow"
    @child-event="animationFunction"
  />
  <signInPopup
    v-model:showPopup="signInPopupShow"
    v-model:sign-in-task="signInTask"
  />
  <coBreeding
    v-model:show-popup="coBreedingpShow"
    @child-event="congratulationSkip"
  />
  <congratulationOne v-model:show-popup="congratulationOneShow" />
  <congratulationTwo v-model:show-popup="congratulationTwoShow" />
  <diaryPopup v-model:show-popup="diaryShow" />
  <task v-model:task-show="taskShow" @child-event="taskSkip" />
  <genderPopup v-model:showPopup="genderPopupShow" />
</template>
<style lang="scss" scoped>
.vessel::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 1; /* 确保遮罩层位于背景之上 */
  pointer-events: none;
}
@keyframes bounce {
  0% {
    transform: translateY(0);
    animation-timing-function: ease-out;
  }
  50% {
    transform: translateY(-8px);
    animation-timing-function: ease-in;
  }
  100% {
    transform: translateY(0);
    animation-timing-function: ease-out;
  }
}
.vessel {
  .positioning-class {
    position: absolute;
    bottom: 88px;
    left: 240px;
    width: 44px;
    height: 61px;
    animation: bounce 0.8s cubic-bezier(0.5, 0.05, 0.5, 1) infinite;
    cursor: pointer;
  }
  width: 100vw;
  height: 100vh;
  background: url("@/assets/image/home.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  overflow: hidden;
  position: relative;
  .right-box {
    position: absolute;
    right: 8px;
    top: 52px;
    display: flex;
    flex-direction: column;
    gap: 11px;
    align-items: center;
    z-index: 2;
    .right-box-item {
      width: 63px;
      height: 63px;
    }
    .right-box-item-arrows-pack-up {
      width: 17px;
      height: 14px;
      transform: rotate(-90deg);
      transform-origin: center;
      transition: transform 0.3s ease;
    }
    .right-more-flex-box {
      display: flex;
      flex-direction: column;
      gap: 5px;
      align-items: center;
      font-family: Source Han Sans;
      font-size: 10px;
      font-weight: 500;
      line-height: 10px;
      letter-spacing: normal;
      color: #ffffff;
      text-align: center;
      .more-item {
        width: 35px;
        height: 36px;
      }
    }
  }
  .bottom-box {
    z-index: 2;
    position: absolute;
    bottom: 28px;
    width: 100%;
    display: flex;
    gap: 48px;
    justify-content: center;
    align-items: flex-end;
    font-family: YouSheBiaoTiHei;
    font-size: 16px;
    font-weight: normal;
    line-height: 10px;
    letter-spacing: normal;
    color: #ffffff;
    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
    .bottom-school {
      width: 56px;
      height: 68px;
    }
  }
}
.walk-animation-bg {
  position: absolute;
}
</style>
